Minikube Sample Project#
Project Overview#
- In this
Minikubesample project we will focusing on deploying a Spring Boot application service and a MongoDB onMinikubeand we can use postman from our host machine to call Spring Boot apis.
MongoDB Deployment#
Setup ConfigMaps#
-
In Kubernetes, a
ConfigMapis an API resource that provides a way to decouple configuration artifacts from your containerized applications. It allows you to store and manage non-sensitive configuration data in key-value pairs.ConfigMapsare commonly used to configure applications, environment variables, command-line arguments, configuration files, or any other configuration data needed by containers running in a Pod. -
Let's create a yaml file name
mongo-config.yamlwith the content as below.
| mongo-config.yaml | |
|---|---|
1 2 3 4 5 6 7 | |
- Okay in this configuration we have the field
kind: ConfigMap. the fieldkindmeans we indicate the type of Kubernetes resource being created and it's value isConfigMap, which is an object used to store configuration data separately from the application code. - Then we have
metadata.name: mongo-configthis is the name of this ConfigMap we will use this name later in deployment configuration. -
Then below field
datawe will havekey: valuepair in the ConfigMap. Currently, we have The key is "mongo-url" and the value is "mongo-service" This means that the ConfigMap will store the value "mongo-service" under the key "mongo-url." Same for themongo-portwith value27017. -
Finally, we will execute the command below to apply the
ConfigMaptominikube
1 | |
-n defaultmeans we will deploy this ConfigMap to namespacedefault.-
-f mongo-config.yamlmeas we specify this file to deploy, -
We can use command below to check which namespace that we are using.
1 | |
- Now, let's open
kubernetes dashboardthen we can see the ConfigMap deployed successfully.
Setup Secrets#
-
In Kubernetes, "Secrets" are a resource type that allows you to store and manage sensitive information, such as passwords, tokens, or any confidential data. Secrets are used to keep this sensitive data secure and separate from the main container image or configuration files, reducing the risk of exposing sensitive information in a compromised container or version control system.
-
Let's create a yaml file name
mongo-secret.yamlwith the content as below.
| mongo-secret.yaml | |
|---|---|
1 2 3 4 5 6 7 8 | |
- In this config file, we have the
kind: Secretwhich is used to store and manage sensitive information securely. - Then we have
metadata.name: mongo-secretthis is the name of thisSecretwe will use this name later in deployment configuration. -
Like
ConfigMapwe also havekey: valuepair in under fielddata. Currently we are storing MongoDB credentials withusernameandpassword. -
Next, we will execute the command below to apply the
Secrettominikube
1 | |
- Same as
ConfigMapafter applying we can see themongo-secretonkubernetes dashboard
Setup Persistent Volume Claim (PVC)#
- In Kubernetes, a Persistent Volume Claim (PVC) is a resource used by applications to request storage resources from the underlying storage infrastructure. PVCs abstract away the details of the underlying storage implementation, allowing developers to request storage without having to know the specific details of the storage infrastructure.
- Let's create a yaml file name
mongo-pvc.yamlwith the content as below.
| mongo-pvc.yaml | |
|---|---|
1 2 3 4 5 6 7 8 9 10 | |
- The
kind: PersistentVolumeClaimindicates the type of Kubernetes resource being created with aPersistentVolumeClaim(PVC). - Then we have
metadata.name: mongo-pvcthis is the name of thisPersistentVolumeClaimwe will use this name later in deployment configuration. -
spec: The "spec" section specifies the desired state of the PVC.accessModes: This field indicates the desired access mode for the persistent volume. In this case, the access mode is set toReadWriteMany. It means that the volume can be mounted as read-write by multiple pods simultaneously, making it suitable for use in scenarios where multiple pods need to read and write to the same volume.resources: This field defines the resource requests for the PVC.requests: This subsection specifies the desired storage capacity for the PVC.storage: 512Mi: This line sets the storage request to 512 megabytes (MiB) of storage capacity. It means that the PVC is requesting a persistent volume with at least 512MiB of storage space.
-
Next, we will execute the command below to apply the
PCVtominikube.
1 | |
Setup Deployment#
-
In Kubernetes, a "Deployment" is a higher-level resource that provides declarative updates for Pods and ReplicaSets. It is used to manage the deployment and scaling of applications within a Kubernetes cluster. Deployments ensure that a specified number of replicas (Pods) are running and available at all times, allowing for application availability, resilience, and easy rolling updates.
-
Let's create a yaml file name
mongo-deployment.yamlwith the content as below.
| mongo-deployment.yaml | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
-
kind: Deployment: The "kind" field indicates the type of Kubernetes resource being created. Here, it's a Deployment, which manages the desired number of replicas of a pod. -
metadata: This section contains metadata about the Deployment, such as its name and labels.name: mongo-deployment: This line defines the name of the Deployment. It will be referred to by this name in other parts of the Kubernetes configuration.labels: app: mongo-app: This line assigns a label to the Deployment, setting it as "mongo-app." Labels are used to identify and select resources in Kubernetes.
-
spec: The "spec" section defines the desired state of the Deployment.replicas: 1: This line specifies that the Deployment should manage one replica (pod) of the MongoDB container.selector: This section defines how the Deployment selects which pods it manages.matchLabels: app: mongo-app: This line specifies that the Deployment should manage pods with the label "app" set to "mongo-app."
template: This section defines the pod template for creating replicas.metadata: This subsection contains metadata for the pod template, such as labels.labels: app: mongo-app: This line sets the "app" label to "mongo-app" for the pods created by the Deployment.
spec: This subsection specifies the desired state of the pod template.containers: This section defines the containers to be run within the pod.name: mongodb: This line sets the name of the container to "mongodb."image: mongo: This line specifies the container image to use, in this case, "mongo," which represents the official MongoDB container image.ports: This section specifies the ports that the container should listen on.containerPort: 27017: This line sets the container port to 27017, which is the default port for MongoDB.
env: This section defines environment variables to be set in the container.name: MONGO_INITDB_ROOT_USERNAME: This line sets the environment variable name to "MONGO_INITDB_ROOT_USERNAME." It is set using the value of a secret key.valueFrom: secretKeyRef: name: mongo-secret: This line indicates that the value for the environment variable is sourced from a secret named "mongo-secret."key: mongo-user: This line specifies that the value is extracted from the "mongo-user" key within the "mongo-secret" secret.
name: MONGO_INITDB_ROOT_PASSWORD: This line sets the environment variable name to "MONGO_INITDB_ROOT_PASSWORD." It is set using the value of a secret key.valueFrom: secretKeyRef: name: mongo-secret: This line indicates that the value for the environment variable is sourced from a secret named "mongo-secret."key: mongo-password: This line specifies that the value is extracted from the "mongo-password" key within the "mongo-secret" secret.
volumeMounts: This section defines volume mounts for the container.name: mongo-storage: This line sets the name of the volume mount to "mongo-storage."mountPath: /data/db: This line specifies the mount path within the container where the persistent storage will be mounted. In this case, it's mounted at "/data/db," which is the default data directory for MongoDB.
volumes: This section defines volumes to be used by the pod.name: mongo-storage: This line sets the name of the volume to "mongo-storage."persistentVolumeClaim: claimName: mongo-pvc: This line indicates that the volume is backed by a PersistentVolumeClaim named "mongo-pvc." The PVC is responsible for dynamically provisioning the required storage.
-
Next, we will execute the command below to apply the
Deploymenttominikube.
1 | |
Setup Service#
-
In Kubernetes, a "Service" is a resource that defines a logical set of Pods and a policy by which to access them. Services enable network connectivity to Pods, abstracting away the underlying details of how Pods are implemented or where they are located within a cluster.
-
Servicesprovide several key benefits as in the table below.
| Aspect | Description |
|---|---|
| Load Balancing | Services provide automatic load balancing across matching Pods, distributing incoming traffic evenly for improved availability. |
| Service Discovery | Services offer stable IP addresses and DNS names, allowing reliable discovery and communication with backend Pods. |
| Network Policies | Services can be used with Network Policies to control and secure network traffic between Pods, defining communication rules. |
| Abstracts Pod Changes | Services ensure Pods remain accessible via a stable IP and DNS name, even when Pods are scaled, replaced, or rescheduled. |
| Support for External Traffic | Services can be configured to expose Pods to external traffic using types like "NodePort" and "LoadBalancer," making applications accessible from outside the cluster. |
- Types of Service.
| Service Type | Description |
|---|---|
| ClusterIP | Default type, exposes the Service on an internal IP within the cluster, suitable for internal communication between services. |
| NodePort | Exposes the Service on a static port on each Node's IP, allowing external access via the Node's IP address and the NodePort. |
| LoadBalancer | Creates an external load balancer in cloud providers (e.g., AWS, GCP, Azure) with an external IP address, used for exposing services to the internet. |
| ExternalName | Maps a Service to a DNS name, enabling Pods within the cluster to access external services by name. |
- Let's create a yaml file name
mongo-service.yamlwith the content as below.
1 2 3 4 5 6 7 8 9 10 11 12 | |
apiVersion: v1: This line specifies the API version of Kubernetes objects used in this manifest. In this case, it's "v1," which is a stable version of the API.kind: Service: The "kind" field indicates that this YAML defines a Kubernetes Service resource. Services are used to expose Pods to network traffic.metadata: This section contains metadata about the Service.name: mongo-service: This line sets the name of the Service to "mongo-service." This name is how you will reference and identify the Service within the Kubernetes cluster.
-
spec: The "spec" section specifies the desired state of the Service.selector: This field is used to select the Pods that the Service will route network traffic to. In this case, it selects Pods with a label "app" set to "mongo-app." This means any Pods in the cluster with the label "app: mongo-app" will be considered part of this Service.ports: This field defines the ports configuration for the Service.- protocol: TCP: This section specifies the protocol to use for the port. It's set to TCP, which is the standard protocol for most network services.name: mongo-port: This line provides a name for the port. This name can be used as an identifier for this port within the Service configuration. In this case, it's named "mongo-port."port: 27017: This line sets the port number on which the Service will listen for incoming network traffic. In this example, it's configured to listen on port 27017, which is a common port for MongoDB database connections.targetPort: 27017: This line specifies the target port on the Pods to which the incoming traffic will be forwarded. In this case, it matches the port number 27017, which is the port that MongoDB typically listens on inside the Pods labeled with "app: mongo-app."
-
Next, we will execute the command below to apply the
Deploymenttominikube.
1 | |
Port Foarward#
Port Forwardis a networking technique that allows a computer, typically a client computer or local machine, to access services or ports on a remote server or another computer securely over a network. It's commonly used for tasks like accessing a remote database, web server, or other network services.- In the context of Kubernetes and containerized applications,
Port Forwardtypically refers to a feature provided by the Kubernetes command-line tool, kubectl. Kubernetes port forwarding enables us to access a specific port of a Pod running within our Kubernetes cluster as if it were running on your local machine. This can be extremely useful for debugging, accessing services that are not exposed externally, or interacting with applications running inside Pods. - We will use the
kubectl port-forwardcommand to specify the name of the Pod and the local and remote port numbers you want to forward. For example:
1 | |
1 2 3 4 5 6 7 | |
1 | |
Testing#
- Okay after the
port-forward, we can useMongoDB Compassto access our mongodb that we deployed on minikube. - We will use the host as
localhost:27017. The port27017is the port that we forwarded on the step above.
- Then we will put the username and password that we defined in the
mongo-secret.yaml. Note we have to decode the username and password for using.
- Finally, we can see the successful connection as in the image below.
Spring Boot Deployment#
Building A Spring Boot Docker Image#
- Before deep dive into the Spring Boot Deployment, we need to take a look about preparing a Spring Boot Docker image. In this example I will take the image from the example Docker With SpringBoot.
- Firstly, let's clone the spring boot project json-schema-validator then we can see the
Dockerfilewith the content as below.
| Dockerfile | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
-
As you can see we have the command
-Dspring.profiles.active=${ENV}. So the spring boot profile will be gotten from environment variable of Docker Container. Then in later steps of Kubernetes deployment we have to make sure setting environment variableENVinto the Docker Container. -
Okay after we built the image and uploaded into our docker repository local.
1 2 3 | |
- Then we will realize that this Docker Image is in the Docker Repository of our local machine not on the Minikube Docker Deamon. So how can we push this docker image
json-schema-validatorinto the Docker Deamon ofMiniKube? - Luckily, Minikube had provided for us a way to do that with the command
minikube docker-env.
1 | |
minikube docker-env: This is a Minikube command that generates a series of environment variables and outputs them to the terminal. These environment variables are specifically configured to point our local Docker client to the Docker daemon running within the Minikube virtual machine.
1 2 3 4 5 6 7 8 | |
-
Then now, we will see, to make the outputs of a command and run them as shell commands, we will use
eval. Theevalcommand is a shell built-in that is used to execute the output of a command as shell commands. It takes the output of the command enclosed in backticks or$()and runs it as if it were a series of commands typed directly into the shell. -
So now, to make our shell point to minikube's docker-daemon, we can run the command below.
1 | |
- So, when we run
eval $(minikube docker-env), we are essentially executing the environment variable settings provided byminikube docker-env. These settings tell our local Docker client to communicate with the Docker daemon inside the Minikube VM rather than the default Docker daemon on our local machine. - Then now, we can republish docker image
json-schema-validatorand it will be contained inside the Minikube Docker Repository.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
- Keep in mind that once we've executed
eval $(minikube docker-env), our local Docker client will remain configured to interact with Minikube until we close the terminal session or reset the environment variables. This allows for a seamless development experience when building and testing containerized applications with Minikube.
Setup ConfigMaps#
- Like we did with the MongoDB before, let's create a yaml file name
springboot-config.yamlwith the content as below.
| springboot-config.yaml | |
|---|---|
1 2 3 4 5 6 | |
- Currently, we have The key is "env" and the value is "dev". We will use this variable to set into the Docker Container environment in later step.
- Next, we will execute the command below to apply the
ConfigMapstominikube.
1 | |
Setup Deployment#
- Let's create a yaml file name
spring-boot-deployment.yamlwith the content as below.
| spring-boot-deployment.yaml | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
apiVersion: apps/v1specifies the API version for this Kubernetes resource. It uses the Apps API version, which is commonly used for Deployments.kind: Deploymentindicates that this YAML defines a Deployment resource. Deployments are used to manage the desired state of a set of replica Pods.metadataprovides metadata about the Deployment:name: spring-boot-deploymentsets the name of the Deployment to "spring-boot-deployment." This is the name by which the Deployment can be referenced in Kubernetes.labelsassigns labels to the Deployment. In this case, the Deployment is labeled with "app: spring-boot-app," which can be used for selecting and organizing resources in Kubernetes.
-
specspecifies the desired state of the Deployment:replicas: 1indicates that the Deployment should manage one replica (Pod) of the Spring Boot application. You can adjust this number to scale the applicationselectordefines the Pod selector used by the Deployment to identify which Pods it should manage:matchLabelsspecifies that the Deployment should manage Pods with the label "app" set to "spring-boot-app." This label corresponds to the labels set earlier in the metadata section.
templatespecifies the Pod template that the Deployment will use for creating replicas:metadataprovides metadata for the Pod template:labelsassigns labels to the Pods created by the Deployment. In this case, the Pods are labeled with "app: spring-boot-app."
specdefines the desired state of the Pods:containersspecifies the containers to run in the Pod:name: spring-boot-appsets the name of the container within the Pod.image: json-schema-validator:0.0.1-SNAPSHOTspecifies the Docker image to use for the container. It appears to be named "json-schema-validator" with the version "0.0.1-SNAPSHOT."imagePullPolicy: Neverindicates that Kubernetes should never attempt to pull the container image from a remote registry. It assumes the image is already available locally.portsdefines the ports that the container should listen on:containerPort: 8080sets the container to listen on port 8080.
env: This section specifies environment variables for the container:- Environment variables like
USERNAME,PASSWORD,DB_URL,PORT, andENVare defined. These variables are set using values from ConfigMaps and Secrets, making it easy to configure the Spring Boot application without modifying the container image.USERNAMEandPASSWORDare sourced from a Secret named "mongo-secret."DB_URLandPORTare sourced from a ConfigMap named "mongo-config."ENVis sourced from a ConfigMap named "spring-boot-config."
-
Next, we will execute the command below to apply the
Deploymenttominikube.
1 | |
Setup Service#
- Let's create a yaml file name
spring-boot-service.yamlwith the content as below.
| spring-boot-service.yaml | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
apiVersion: v1: This specifies the Kubernetes API version for this resource. In this case, it's using the "v1" version, which is the core Kubernetes API version.kind: Service: This indicates that this YAML configuration defines a Kubernetes Service resource. Services are used to expose and make network connections to Pods within the cluster.metadata: This section provides metadata about the Service:name: spring-boot-service: It sets the name of the Service to "spring-boot-service." This name is how the Service can be referenced within the Kubernetes cluster.
-
spec: This section specifies the desired state of the Service:type: NodePort: It indicates that this Service should be of type NodePort. NodePort is one of the Service types in Kubernetes and exposes the Service on a static port on each Node in the cluster. It allows external traffic to reach the Service using the Node's IP address and the NodePort.selector: This field defines a selector that determines which Pods the Service should route traffic to. In this case, the selector specifies that the Service should route traffic to Pods with the label "app" set to "spring-boot-app." This label corresponds to the labels set on the Pods.ports: This section specifies the ports configuration for the Service:- protocol: TCP: This section specifies the protocol to use for the port, which is TCP in this case.name: spring-boot-port: It provides a name for the port. This name can be used as an identifier for this port within the Service configuration.port: 8080: This line sets the port number on which the Service will listen for incoming network traffic. In this example, it's configured to listen on port 8080.targetPort: 8080: This line specifies the target port on the Pods to which incoming traffic will be forwarded. It matches the port number 8080, which is the port that the Spring Boot application inside the Pods is listening on.nodePort: 30000: This line sets the NodePort, which is the external port that will be open on each Node in the cluster. In this case, the Service will be accessible externally on NodePort 30000.
-
Next, we will execute the command below to apply the
Servicetominikube.
1 | |
- Okay so, we finished deployments for MongoDB and Spring Boot Service which will connect to MongoDB. Let's continue to test it in following section.
Testing#
- Because in Minikube we have
- Now, let's run the command below to get the
minikube node ip.
1 | |
1 2 | |
- So, we can access to the Spring Boot application which is deployed in a Node of Minikube with this Node Ip and the Node port
30000that we exported in thespring-boot-service.yamlbefore. - Let's open Postman and try to call some apis of Spring Booot service with the IP and PORT above.
- We can see that we can store and get json schema from MongoDB with 2 apis from our Spring Boot application and they are all deployed in Minikube Node.
See Also#
- Kubernetes Introduction
- Minikube Introduction
- Docker With SpringBoot
- Spring Boot With Json Schema Validator













